//position of the camera, for specular light
float3 CameraPosition; 

//this is used to compute the world-position
float4x4 InvertViewProjection; 

matrix ViewMatrix;
matrix Projection;
matrix World;

float3 lightCenter;

vector AmbientMtrl;
vector DiffuseMtrl;
vector LightDirection;

texture Texture;
sampler diffuseSampler = sampler_state
{
	Texture = <Texture>;
	MagFilter = LINEAR;
	MinFilter = LINEAR;
	Mipfilter = LINEAR;
};

texture SpecTexture;
sampler specSampler = sampler_state
{
	Texture = <SpecTexture>;
	MagFilter = LINEAR;
	MinFilter = LINEAR;
	Mipfilter = LINEAR;
};

// Input and Output structures.
struct VertexShaderInput
{
	float4 Position : POSITION0;
	float2 TexCoord : TEXCOORD0;
	float3 Normal : NORMAL0;
};

struct VertexShaderOutput
{
	float4 Position : POSITION0;
	float4 Position3D : TEXCOORD0;
	float2 TexCoord : TEXCOORD1;
	float3 Normal : TEXCOORD2;
};

// Main
VertexShaderOutput vs(VertexShaderInput input)
{
	// zero out all members of the output instance.
	VertexShaderOutput output = (VertexShaderOutput)0;

	float4 worldPosition = mul(input.Position, World);
	float4 viewPosition = mul(worldPosition, ViewMatrix);
	output.Position = mul(viewPosition, Projection);
	output.Position3D = worldPosition;
	
	output.TexCoord = input.TexCoord;
	output.Normal = input.Normal;
	
	return output;
}


float4 PixelShaderFunction(VertexShaderOutput input)  : COLOR0
{
	float4 LightDir = (vector)0;
	
	LightDir.xyz = LightDirection.xyz;
	LightDir.w = 0;
	
	LightDir = mul(LightDir, ViewMatrix);
	
	input.Normal = mul(input.Normal, ViewMatrix);
	
	float s = dot(LightDir, input.Normal);
	
	if( s < 0.0f )
	{
		s = 0.0f;
	}
	
	//reflection vector
	float3 reflectionVector = normalize(reflect(LightDirection, input.Normal));

	//camera-to-surface vector
	float3 directionToCamera = normalize(CameraPosition - input.Position3D);

	//compute specular light
	float spec = tex2D(specSampler, input.TexCoord).r;
	float specularLight = spec * 0.9f *  pow(saturate(dot(reflectionVector, directionToCamera)), 20.0f);
	
	float4 diffuse = tex2D(diffuseSampler, input.TexCoord);
	
	/*
	// Shadow mapping
	float4 proj = 0;
	proj = mul(input.Position3D, lightWorldViewProj);
	float2 projectedTexCoords;
	projectedTexCoords[0] =  proj.x/proj.w/2.0f + 0.5f;
	projectedTexCoords[1] = -proj.y/proj.w/2.0f + 0.5f;
	float4 moments = tex2D(shadowMapSampler, projectedTexCoords).r;
	float offset = 0.001f;
	float len = (proj.z / proj.w) - offset;
	float shadow = step(len, moments.x);
	*/
	
	float center = 1.0f/ distance(float4(0,0,0,0), float4(input.Position3D.x, 0, input.Position3D.z, 0)) / 2.0f;
	

	return  (s * (diffuse * DiffuseMtrl)) + (AmbientMtrl) + specularLight;
}

technique diffuse
{
	pass p0
	{
		VertexShader = compile vs_2_0 vs();
		PixelShader = compile ps_2_0 PixelShaderFunction();
	}
}